<?php
namespace Abo\Larasearch\V0\SyncDatabase\Adapter;
use Abo\Larasearch\V0\ElasticSearch\EsBuilder;

/**
 * Class ElasticsearchSyncAdapter
 * Description: Elasticsearch 数据同步适配器
 * @package Abo\Larasearch\SyncDatabase\Adapter
 */
class ElasticsearchSyncAdapter
{
    /** @var $EsBuilder EsBuilder */
    private $EsBuilder;
    protected $index, $type, $key;

    public function __construct( string $index, string $type, string $key = 'id' )
    {
        $this->index = $index;
        $this->type = $type;
        $this->key = $key;
    }

    /**
     * 同步新增逻辑
     * @param array $insertData
     * @return int
     * @throws \Exception
     */
    public function syncInsertData( array $insertData ):int
    {
        if ( !$insertData ) {
            return 0;
        }
        $insertData = json_decode( json_encode( $insertData ), true ); // stdClass 转 array

        $this->idKeyCheckData( current( $insertData ) );

        $i2Count = 0;
        foreach ( $insertData as $v2Data ) {
            if ( !isset( $v2Data[ $this->key ] ) ) {
                continue;
            }

            $this->clientInstance()->docInsert( $v2Data, $this->key );
            $i2Count++;
        }

        return $i2Count;
    }

    /**
     * 同步更新逻辑
     * @param array $updateData
     * @return bool|int
     * @throws \Exception
     */
    public function syncUpdateData( array $updateData ):int
    {
        if ( !$updateData ) {
            return 0;
        }
        $updateData = json_decode( json_encode( $updateData ), true );
        $this->idKeyCheckData( current( $updateData ) );

        $i2Count = 0;
        foreach ( $updateData as $v2Data ) {
            if ( !isset( $v2Data[ $this->key ] ) ) {
                continue;
            }

            $this->clientInstance()->docUpdate( $v2Data[ $this->key ], $v2Data );
            $i2Count++;
        }

        return $i2Count;
    }

    /**
     * 同步删除数据
     * @param array $deleteIds => [ 1, 2, 3, 10175 ]
     * @return int
     */
    public function syncDeleteData( array $deleteIds ):int
    {
        if ( !$deleteIds ) {
            return 0;
        }

        $i2Count = 0;
        foreach ( $deleteIds as $v2Id ) {
            if ( !$v2Id ) {
                continue;
            }
            $this->clientInstance()->docDelete( $v2Id );
            $i2Count++;
        }

        return $i2Count;
    }

    /**
     * 单个同步数据,检查设置主键是否存在
     * @param array $data 同步数据
     * @return bool
     * @throws \Exception
     */
    protected function idKeyCheckData( array $data ):bool
    {
        if ( !$data ) {
            return true;
        }

        if ( !isset( $data[ $this->key ] ) ) {
            throw new \Exception( '同步数据中无 设置主键 存在', false );
        }

        return true;
    }

    /**
     * 客户端单例
     * @return EsBuilder
     */
    protected function clientInstance():EsBuilder
    {
        if ( !$this->EsBuilder ) {
            /** @var $EsBuilder EsBuilder */
            $EsBuilder = app( EsBuilder::class );

            if ( $this->index ) {
                $EsBuilder->index( $this->index );
            }
            if ( $this->type ) {
                $EsBuilder->type( $this->type );
            }

            $this->EsBuilder = $EsBuilder;
        }

        return $this->EsBuilder;
    }
}